/*
* JSA Test Suit
*
* @package jsa-tests
* @author sheiko
* @version jsa.js, v 2.0
* @license MIT
* @copyright (c) Dmitry Sheiko http://www.dsheiko.com
* @jscs standard:Jquery
* Code style: http://docs.jquery.com/JQuery_Core_Style_Guidelines
*/
/*jshint sub:true*/
/*global module: false */
(function( global, module, undefined ) {
    var jsa = global.jsa;

    module.TestConstructor = {
        SuperType : function( arg ) {
            return {
                prop: null
            }
        },
        SubType: function( arg ) {
            return {
                "__extends__": this.SuperType,
                "__constructor__": function( arg ) {
                    this.prop = arg;
                }
            }
        }
    };

    /**
     * Check the behavior derived from WidgetAbstract
     */
    module.TestWidget = function( settings ) {
         return {
             "__extends__": jsa.WidgetAbstract,
             HTML_PARSER : {
               wrapper : 'div.wrapper',
               subject : 'p.subject'
             },
             init : function() {
                 this.node.boundingBox.addClass('init');
             },
             syncUI : function() {
                 this.node.boundingBox.addClass('syncUI');
             },
             renderUI : function() {
                 this.node.boundingBox.addClass('renderUI');
                 if (this.node.wrapper.length) {
                     this.node.boundingBox.addClass('wrapperFound');
                 }
                 if (this.node.subject.length) {
                     this.node.boundingBox.addClass('subjectFound');
                 }
             }
          }
     };
     /**
      * Checks module inheritance
      */
     module.log = [];

     module.AbstractModule = function( settings ) {
         var _privateVar = "abstract-private-access";
         return {
             "__extends__": jsa.WidgetAbstract,
             inheritedProp : "inherited-prop-access",
             inheritedPrivilegedMethod : function() {
                 return _privateVar;
             },
             init : function() {
                module.log.push('abstract-module-initialized');
             },
             renderUI : function() {
                 module.log.push('abstract-module-rendered');
             },
             syncUI : function() {
                 module.log.push('abstract-module-synchronized');
             }
         }
     };

     module.ConcreteModule = function( settings ) {
         return {
            "__extends__": module.AbstractModule,
            /** @property arr */
            arr: [],
            init : function() {
                module.log.push('concrete-module-initialized');
            },
            renderUI : function() {
                 module.log.push('abstract-module-rendered');
            },
            syncUI : function() {
                 module.log.push('abstract-module-synchronized');
            }
          }
     };
     /**
      * Check interface implementation
      */
     module.ViolatingModule = function() {
         return {
             "__implements__": module.ConcreteInterface
         };
     };

     module.InjectedDependency = function() {
         return {
         };
     };

     module.ConcreteInterface = {
         requeriedMethod : [ "string", module.InjectedDependency ]
     };

     module.StrictModule = function() {
         return {
             "__implements__": module.ConcreteInterface,
             requeriedMethod : function() {
             }
         }
     };
     /*
      * Check design by contract implementation
      */
     module.ConcreteContract = {
         methodA : [ "number", module.InjectedDependency ],
         methodB : {
              onEntry: [ "number", module.InjectedDependency ],
              validators: [ function( arg ){
                  return arg > 10;
              } ],
              onExit: "string"
          },
          methodC : {
              onExit: "string"
          }
     };
     module.EmployedModule = function() {
         return {
             "__contract__": module.ConcreteContract,
             methodA : function() {
             },
             methodB : function() {
                 return "a string";
             },
             methodC : function() {
                 return []; // Not a string
             }
         }
     };


     module.MixinA = {
         propertyA: "propertyA"
     };
     module.MixinB = {
         propertyB: "propertyB"
     };
     module.Silo = function() {
         return {
             "__mixin__": [ module.MixinA, module.MixinB ],
             ownPropery: "Own property"
         }
     };


 })( this, module || {} );
